package com.liang.service.impl;

import com.liang.entity.GoodsStore;
import com.liang.respository.GoodsStoreRespository;
import com.liang.rlock.RedisLockD;
import com.liang.service.GoodsStoreService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Optional;

/**
 * Created with Intellij IDEA
 *
 * @Auther: liangjy
 * @Date: 2022/01/07/14:32
 * @Description:
 */
@Service
public class GoodsStoreServiceImpl implements GoodsStoreService {

    @Autowired
    private GoodsStoreRespository goodsStoreRespository;

    @Autowired
    private RedisLockD redisLock;

    /**
     * 超时时间 5s
     */
    private static final int TIMEOUT = 5 * 1000;

    /**
     * 根据产品编号更新库存
     *
     * @param code  商品编号
     * @param count 前端传过来的数量
     * @return
     */
    @Override
    public String updateGoodsStore(String code, int count) {
        //上锁
        long time = System.currentTimeMillis() + TIMEOUT;
        /**
         * 拿不到资源 那么就会等待
         */
        if (!redisLock.lock(code, String.valueOf(time))) {
            return "排队人数太多，请稍后再试.";
        }
        System.out.println("获得锁的时间戳：" + String.valueOf(time));
        try {
            GoodsStore goodsStore = getGoodsStore(code);
            if (goodsStore != null) {
                if (goodsStore.getStore() <= 0) {
                    return "对不起，卖完了，库存为：" + goodsStore.getStore();
                }
                if (goodsStore.getStore() < count) {
                    return "对不起，库存不足，库存为：" + goodsStore.getStore() + " 您的购买数量为：" + count;
                }
                System.out.println("剩余库存：" + goodsStore.getStore());
                System.out.println("扣除库存：" + count);
                int store = goodsStore.getStore();
                count = (store - count);
                goodsStoreRespository.updateStore(code, count);
                try {
                    //为了更好的测试多线程同时进行库存扣减，在进行数据更新之后先等1秒，让多个线程同时竞争资源
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return "恭喜您，购买成功！";
            } else {
                return "获取库存失败。";
            }
        } finally {
            //释放锁
            redisLock.release(code, String.valueOf(time));
            System.out.println("释放锁的时间戳：" + String.valueOf(time));
        }
    }

    /**
     * 获取库存对象
     *
     * @param code
     * @return
     */
    @Override
    public GoodsStore getGoodsStore(String code) {
        Optional<GoodsStore> optional = goodsStoreRespository.findById(code);
        return optional.get();
    }
}
